package com.shrct.businessprocess.budget.impl;

import com.google.common.collect.Iterables;
import com.shrct.businessprocess.budget.RCBudget;
import com.shrct.businessprocess.budget.RCBudgetTaskStatus;
import com.shrct.businessprocess.budget.RCCost4ACTItem;
import com.shrct.businessprocess.budget.RCCostBreakDown;
import com.shrct.businessprocess.budget.RCEX2Budget;
import com.shrct.businessprocess.budget.RCEX2ExtBudget;
import com.shrct.businessprocess.budget.RCEXBaseBudget;
import com.shrct.businessprocess.budget.impl.RCBudgetImpl;
import com.shrct.businessprocess.budget.proxy.RCEX2ExtBudgetProxy;
import com.shrct.businessprocess.project.RCExchangeRate;
import com.shrct.businessprocess.project.RCProjectMoney;
import edu.fudan.mylang.common.NumberExtensions;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.DoubleExtensions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;

@Entity
@DiscriminatorValue("RCEX2EXTBUDGET_TYPE")
public class RCEX2ExtBudgetImpl extends RCBudgetImpl implements RCEX2ExtBudget {
  public RCEX2ExtBudgetImpl() {
    super();
  }
  
  public RCEX2ExtBudgetImpl(final RCCostBreakDown cbd) {
    super( cbd);
    
  }
  
  public RCProjectMoney getContractPrice() {
    RCProjectMoney _rCProjectMoney = new RCProjectMoney();
    final Procedure1<RCProjectMoney> _function = new Procedure1<RCProjectMoney>() {
        public void apply(final RCProjectMoney it) {
          it.setAmount(Double.valueOf(0d));
          RCCostBreakDown _cbd = RCEX2ExtBudgetImpl.this.getCbd();
          RCExchangeRate _exchangeRate = _cbd.getExchangeRate();
          it.setExchange(_exchangeRate);
        }
      };
    RCProjectMoney _doubleArrow = ObjectExtensions.<RCProjectMoney>operator_doubleArrow(_rCProjectMoney, _function);
    return _doubleArrow;
  }
  
  public Double getContractTaxRate() {
    return Double.valueOf(0d);
  }
  
  public Double getNetTaxRate() {
    return Double.valueOf(0d);
  }
  
  public RCProjectMoney getNetInvoiceTax() {
    RCProjectMoney _rCProjectMoney = new RCProjectMoney();
    final Procedure1<RCProjectMoney> _function = new Procedure1<RCProjectMoney>() {
        public void apply(final RCProjectMoney it) {
          it.setAmount(Double.valueOf(0d));
          RCCostBreakDown _cbd = RCEX2ExtBudgetImpl.this.getCbd();
          RCExchangeRate _exchangeRate = _cbd.getExchangeRate();
          it.setExchange(_exchangeRate);
        }
      };
    RCProjectMoney _doubleArrow = ObjectExtensions.<RCProjectMoney>operator_doubleArrow(_rCProjectMoney, _function);
    return _doubleArrow;
  }
  
  public RCProjectMoney getContractInvoiceTax() {
    RCProjectMoney _rCProjectMoney = new RCProjectMoney();
    final Procedure1<RCProjectMoney> _function = new Procedure1<RCProjectMoney>() {
        public void apply(final RCProjectMoney it) {
          it.setAmount(Double.valueOf(0d));
          RCCostBreakDown _cbd = RCEX2ExtBudgetImpl.this.getCbd();
          RCExchangeRate _exchangeRate = _cbd.getExchangeRate();
          it.setExchange(_exchangeRate);
        }
      };
    RCProjectMoney _doubleArrow = ObjectExtensions.<RCProjectMoney>operator_doubleArrow(_rCProjectMoney, _function);
    return _doubleArrow;
  }
  
  public Iterable<RCCost4ACTItem> getCost4ACItems() {
    RCCost4ACTItem _rCCost4ACTItem = new RCCost4ACTItem();
    final Procedure1<RCCost4ACTItem> _function = new Procedure1<RCCost4ACTItem>() {
        public void apply(final RCCost4ACTItem it) {
          it.setBudget(RCEX2ExtBudgetImpl.this);
          String _entityName = RCEX2ExtBudgetImpl.this.getEntityName();
          it.setTitle(_entityName);
          RCProjectMoney _actualCostAmount = RCEX2ExtBudgetImpl.this.getActualCostAmount();
          Double _hostAmount = _actualCostAmount.toHostAmount();
          it.setAmount(_hostAmount);
          Double _amount = it.getAmount();
          String _plus = ("=======>" + _amount);
          InputOutput.<String>println(_plus);
          it.setTaxRate(Double.valueOf(0d));
          it.setDate(null);
        }
      };
    RCCost4ACTItem _doubleArrow = ObjectExtensions.<RCCost4ACTItem>operator_doubleArrow(_rCCost4ACTItem, _function);
    ArrayList<RCCost4ACTItem> _newArrayList = CollectionLiterals.<RCCost4ACTItem>newArrayList(_doubleArrow);
    return _newArrayList;
  }
  
  public RCBudgetTaskStatus getBudgetTaskStatus() {
    RCCostBreakDown _cbd = this.getCbd();
    Collection<RCBudget> _budgets = _cbd.getBudgets();
    Iterable<RCEX2Budget> _filter = Iterables.<RCEX2Budget>filter(_budgets, RCEX2Budget.class);
    RCEX2Budget _head = IterableExtensions.<RCEX2Budget>head(_filter);
    RCBudgetTaskStatus _budgetTaskStatus = _head.getBudgetTaskStatus();
    return _budgetTaskStatus;
  }
  
  /**
   * 判断该预算项目作为任务计划是否已经执行完毕
   */
  public Boolean seemsFinished() {
    RCCostBreakDown _cbd = this.getCbd();
    Collection<RCBudget> _budgets = _cbd.getBudgets();
    Iterable<RCEX2Budget> _filter = Iterables.<RCEX2Budget>filter(_budgets, RCEX2Budget.class);
    RCEX2Budget _head = IterableExtensions.<RCEX2Budget>head(_filter);
    Boolean _seemsFinished = _head.seemsFinished();
    return _seemsFinished;
  }
  
  /**
   * =IF(SUM(F33:F34)>=(D40-(SUM(F6:F34)+F37+F38));(F33+F34)*20%;F34/(1-10%)*10%)
   *        if(市场费1+2 >= 销售价 - 除去附加费外的成本)  市场费1+2 * 0.2  else  市场费2/0.9*0.1
   */
  private RCProjectMoney getCostAmount(final Function1<? super RCBudget,? extends Double> amountCalc) {
    RCProjectMoney _xblockexpression = null;
    {
      RCCostBreakDown _cbd = this.getCbd();
      Collection<RCBudget> _budgets = _cbd.getBudgets();
      Iterable<RCEXBaseBudget> _filter = Iterables.<RCEXBaseBudget>filter(_budgets, RCEXBaseBudget.class);
      final Function1<RCEXBaseBudget,Double> _function = new Function1<RCEXBaseBudget,Double>() {
          public Double apply(final RCEXBaseBudget it) {
            Double _apply = amountCalc.apply(it);
            return _apply;
          }
        };
      Iterable<Double> _map = IterableExtensions.<RCEXBaseBudget, Double>map(_filter, _function);
      final Function2<Double,Double,Double> _function_1 = new Function2<Double,Double,Double>() {
          public Double apply(final Double d1, final Double d2) {
            double _plus = DoubleExtensions.operator_plus(d1, d2);
            return Double.valueOf(_plus);
          }
        };
      Double _reduce = IterableExtensions.<Double>reduce(_map, _function_1);
      final Double allEXMoney = NumberExtensions.nullsafe(_reduce);
      RCCostBreakDown _cbd_1 = this.getCbd();
      RCProjectMoney _contractPrice = _cbd_1.getContractPrice();
      final Double allContractPrice = _contractPrice.toHostAmount();
      RCCostBreakDown _cbd_2 = this.getCbd();
      Collection<RCBudget> _budgets_1 = _cbd_2.getBudgets();
      final Function1<RCBudget,Boolean> _function_2 = new Function1<RCBudget,Boolean>() {
          public Boolean apply(final RCBudget it) {
            boolean _not = (!(it instanceof RCEX2ExtBudget));
            return Boolean.valueOf(_not);
          }
        };
      Iterable<RCBudget> _filter_1 = IterableExtensions.<RCBudget>filter(_budgets_1, _function_2);
      final Function1<RCBudget,Double> _function_3 = new Function1<RCBudget,Double>() {
          public Double apply(final RCBudget it) {
            Double _apply = amountCalc.apply(it);
            return _apply;
          }
        };
      Iterable<Double> _map_1 = IterableExtensions.<RCBudget, Double>map(_filter_1, _function_3);
      final Function2<Double,Double,Double> _function_4 = new Function2<Double,Double,Double>() {
          public Double apply(final Double d1, final Double d2) {
            double _plus = DoubleExtensions.operator_plus(d1, d2);
            return Double.valueOf(_plus);
          }
        };
      Double _reduce_1 = IterableExtensions.<Double>reduce(_map_1, _function_4);
      final Double allNetPriceExcludeExt = NumberExtensions.nullsafe(_reduce_1);
      RCCostBreakDown _cbd_3 = this.getCbd();
      Collection<RCBudget> _budgets_2 = _cbd_3.getBudgets();
      Iterable<RCEX2Budget> _filter_2 = Iterables.<RCEX2Budget>filter(_budgets_2, RCEX2Budget.class);
      RCEX2Budget _head = IterableExtensions.<RCEX2Budget>head(_filter_2);
      final Double ex2Money = amountCalc.apply(_head);
      double _xifexpression = (double) 0;
      double _minus = DoubleExtensions.operator_minus(allContractPrice, allNetPriceExcludeExt);
      boolean _greaterEqualsThan = ((allEXMoney).doubleValue() >= _minus);
      if (_greaterEqualsThan) {
        double _multiply = ((allEXMoney).doubleValue() * 0.2);
        _xifexpression = _multiply;
      } else {
        double _divide = ((ex2Money).doubleValue() / 0.9);
        double _multiply_1 = (_divide * 0.1);
        _xifexpression = _multiply_1;
      }
      final double amount = _xifexpression;
      RCProjectMoney _rCProjectMoney = new RCProjectMoney();
      final Procedure1<RCProjectMoney> _function_5 = new Procedure1<RCProjectMoney>() {
          public void apply(final RCProjectMoney it) {
            it.setAmount(Double.valueOf(amount));
            RCCostBreakDown _cbd = RCEX2ExtBudgetImpl.this.getCbd();
            RCExchangeRate _exchangeRate = _cbd.getExchangeRate();
            it.setExchange(_exchangeRate);
          }
        };
      RCProjectMoney _doubleArrow = ObjectExtensions.<RCProjectMoney>operator_doubleArrow(_rCProjectMoney, _function_5);
      _xblockexpression = (_doubleArrow);
    }
    return _xblockexpression;
  }
  
  public RCProjectMoney getNetPrice() {
    final Function1<RCBudget,Double> _function = new Function1<RCBudget,Double>() {
        public Double apply(final RCBudget it) {
          RCProjectMoney _netPrice = it.getNetPrice();
          Double _hostAmount = _netPrice.toHostAmount();
          return _hostAmount;
        }
      };
    RCProjectMoney _costAmount = this.getCostAmount(_function);
    return _costAmount;
  }
  
  public String getTypeId() {
    return "RCEX2ExtBudget";
  }
  
  public RCProjectMoney getActualCostAmount() {
    final Function1<RCBudget,Double> _function = new Function1<RCBudget,Double>() {
        public Double apply(final RCBudget it) {
          RCProjectMoney _actualCostAmount = it.getActualCostAmount();
          Double _hostAmount = _actualCostAmount.toHostAmount();
          return _hostAmount;
        }
      };
    RCProjectMoney _costAmount = this.getCostAmount(_function);
    return _costAmount;
  }
  
  public static RCEX2ExtBudget create(final RCCostBreakDown cbd, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.budget.RCEX2ExtBudget rCEX2ExtBudget = new com.shrct.businessprocess.budget.impl.RCEX2ExtBudgetImpl(
    	cbd
    );
    objectFactory.create(rCEX2ExtBudget);
    return rCEX2ExtBudget;			
    
  }
  
  public static RCEX2ExtBudget createRCEX2ExtBudgetImpl(final RCCostBreakDown cbd, final IObjectFactory objectFactory, final Procedure1<RCEX2ExtBudget> init) {
    com.shrct.businessprocess.budget.RCEX2ExtBudget rCEX2ExtBudget = new com.shrct.businessprocess.budget.impl.RCEX2ExtBudgetImpl(
    	cbd
    );
    objectFactory.create(rCEX2ExtBudget);
    init.apply(rCEX2ExtBudget);
    
    return rCEX2ExtBudget;			
    
  }
  
  public RCEX2ExtBudgetProxy toProxy() {
    com.shrct.businessprocess.budget.proxy.RCEX2ExtBudgetProxy proxy = new com.shrct.businessprocess.budget.proxy.RCEX2ExtBudgetProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
